import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os

from UI.utils.predict import PredictionParameters


class PredictionFrame:
    """
    预测参数设置界面
    """

    def __init__(self, parent, params_manager):
        self.parent = parent
        self.params_manager = params_manager

        # 创建主框架
        self.frame = tk.Frame(parent, bg="white", padx=20, pady=20)
        self.frame.pack(fill=tk.BOTH, expand=True)

        # 创建标题标签
        title_label = tk.Label(
            self.frame,
            text="预测参数",
            font=("微软雅黑", 14, "bold"),
            bg="white",
            fg="#333"
        )
        title_label.pack(pady=(0, 20))
        self.PredictionParameters=PredictionParameters()
        # 创建参数设置区域
        self.create_parameter_section()

        # 创建操作按钮区域
        self.create_control_buttons()

        # 绑定事件
        self.bind_events()

        # 初始化界面
        self.load_default_values()

    def create_parameter_section(self):
        """创建参数设置区域"""
        # 创建参数框架
        param_frame = tk.Frame(self.frame, bg="white")
        param_frame.pack(fill=tk.BOTH, expand=True)

        # 参数列表 - 按两列分组
        parameters = [
            ('project', 'Project'),
            ('name', 'Name'),
            ('show', 'Show'),
            ('save_frames', 'Save Frames'),
            ('save_txt', 'Save TXT'),
            ('save_conf', 'Save Conf'),
            ('save_crop', 'Save Crop'),
            ('show_labels', 'Show Labels'),
            ('show_conf', 'Show Conf'),
            ('show_boxes', 'Show Boxes')
        ]

        # 创建两列布局
        left_column = tk.Frame(param_frame, bg="white")
        left_column.grid(row=0, column=0, sticky="nsew", padx=(0, 10))

        right_column = tk.Frame(param_frame, bg="white")
        right_column.grid(row=0, column=1, sticky="nsew", padx=(10, 0))

        # 配置列权重
        param_frame.columnconfigure(0, weight=1)
        param_frame.columnconfigure(1, weight=1)

        # 将参数分配到两列
        left_params = parameters[:5]  # 前5个参数在左列
        right_params = parameters[5:]  # 后5个参数在右列

        # 创建左列参数
        row = 0
        for i, (param_key, display_name) in enumerate(left_params):
            # 创建行框架
            row_frame = tk.Frame(left_column, bg="white")
            row_frame.grid(row=row, column=0, sticky="ew", pady=5, padx=5)

            # 创建标签
            label = tk.Label(
                row_frame,
                text=display_name + ":",
                bg="white",
                font=("微软雅黑", 10),
                width=12,
                anchor="w"
            )
            label.pack(side=tk.LEFT, padx=(0, 10))

            # 创建输入框
            if param_key == 'show' or param_key == 'save_frames' or param_key == 'save_txt' or \
                    param_key == 'save_conf' or param_key == 'save_crop' or param_key == 'show_labels' or \
                    param_key == 'show_conf' or param_key == 'show_boxes':
                # 布尔值使用复选框
                var = tk.BooleanVar(value=self.params_manager.get_param(param_key))
                checkbox = tk.Checkbutton(
                    row_frame,
                    variable=var,
                    onvalue=True,
                    offvalue=False,
                    bg="white",
                    font=("微软雅黑", 10)
                )
                checkbox.pack(side=tk.LEFT)
                # 存储变量引用
                setattr(self, f"{param_key}_var", var)
            else:
                # 文本输入框
                entry_var = tk.StringVar(value=str(self.params_manager.get_param(param_key)))
                entry = tk.Entry(
                    row_frame,
                    textvariable=entry_var,
                    width=15,
                    font=("微软雅黑", 10)
                )
                entry.pack(side=tk.LEFT)
                # 存储变量引用
                setattr(self, f"{param_key}_var", entry_var)

            row += 1

        # 创建右列参数
        row = 0
        for i, (param_key, display_name) in enumerate(right_params):
            # 创建行框架
            row_frame = tk.Frame(right_column, bg="white")
            row_frame.grid(row=row, column=0, sticky="ew", pady=5, padx=5)

            # 创建标签
            label = tk.Label(
                row_frame,
                text=display_name + ":",
                bg="white",
                font=("微软雅黑", 10),
                width=12,
                anchor="w"
            )
            label.pack(side=tk.LEFT, padx=(0, 10))

            # 创建输入框
            if param_key == 'show' or param_key == 'save_frames' or param_key == 'save_txt' or \
                    param_key == 'save_conf' or param_key == 'save_crop' or param_key == 'show_labels' or \
                    param_key == 'show_conf' or param_key == 'show_boxes':
                # 布尔值使用复选框
                var = tk.BooleanVar(value=self.params_manager.get_param(param_key))
                checkbox = tk.Checkbutton(
                    row_frame,
                    variable=var,
                    onvalue=True,
                    offvalue=False,
                    bg="white",
                    font=("微软雅黑", 10)
                )
                checkbox.pack(side=tk.LEFT)
                # 存储变量引用
                setattr(self, f"{param_key}_var", var)
            else:
                # 文本输入框
                entry_var = tk.StringVar(value=str(self.params_manager.get_param(param_key)))
                entry = tk.Entry(
                    row_frame,
                    textvariable=entry_var,
                    width=15,
                    font=("微软雅黑", 10)
                )
                entry.pack(side=tk.LEFT)
                # 存储变量引用
                setattr(self, f"{param_key}_var", entry_var)

            row += 1

    def create_control_buttons(self):
        """创建操作按钮区域"""
        button_frame = tk.Frame(self.frame, bg="white")
        button_frame.pack(pady=20)

        # 创建按钮
        load_btn = tk.Button(
            button_frame,
            text="加载配置",
            command=self.load_config,
            bg="#4CAF50",
            fg="white",
            font=("微软雅黑", 10),
            padx=15,
            pady=5
        )
        load_btn.pack(side=tk.LEFT, padx=5)

        save_btn = tk.Button(
            button_frame,
            text="保存配置",
            command=self.save_config,
            bg="#2196F3",
            fg="white",
            font=("微软雅黑", 10),
            padx=15,
            pady=5
        )
        save_btn.pack(side=tk.LEFT, padx=5)

        reset_btn = tk.Button(
            button_frame,
            text="重置默认",
            command=self.reset_defaults,
            bg="#FF9800",
            fg="white",
            font=("微软雅黑", 10),
            padx=15,
            pady=5
        )
        reset_btn.pack(side=tk.LEFT, padx=5)

        # 添加到实例属性
        self.load_button = load_btn
        self.save_button = save_btn
        self.reset_button = reset_btn
    def bind_events(self):
        """绑定事件"""
        # 绑定键盘快捷键
        self.frame.bind('<Control-s>', lambda e: self.save_config())
        self.frame.bind('<Control-l>', lambda e: self.load_config())

    def load_default_values(self):
        """加载默认值到界面"""
        # 获取所有参数
        params = self.params_manager.get_all_params()

        # 更新界面控件
        for key, value in params.items():
            if hasattr(self, f"{key}_var"):
                var = getattr(self, f"{key}_var")
                if isinstance(var, tk.BooleanVar):
                    var.set(value)
                elif isinstance(var, tk.StringVar):
                    var.set(str(value))

    def load_config(self):
        """加载配置文件"""
        try:
            # 获取当前文件所在目录
            current_dir = os.path.dirname(os.path.abspath(__file__))
            # 向上两级找到项目根目录（因为当前在 UI/ui/ 下）
            project_root = os.path.dirname(os.path.dirname(current_dir))

            # 构建配置文件路径
            config_path = os.path.join(project_root, 'cfg', 'predict.yaml')

            # 检查配置文件是否存在
            if os.path.exists(config_path):
                # 使用实例调用方法，而不是类调用
                success = self.params_manager.load_from_yaml(config_path)
                if success:
                    self.load_default_values()
                else:
                    messagebox.showerror("错误", "无法加载配置文件！")
            else:
                messagebox.showerror("错误", f"配置文件不存在: {config_path}")
        except Exception as e:
            messagebox.showerror("错误", f"加载配置文件时发生异常: {str(e)}")


    def save_config(self):
        """保存配置文件到默认位置（只更新界面中的参数）"""
        try:
            # 获取当前文件所在目录
            current_dir = os.path.dirname(os.path.abspath(__file__))
            # 向上两级找到项目根目录（因为当前在 UI/ui/ 下）
            project_root = os.path.dirname(os.path.dirname(current_dir))

            # 构建配置文件路径
            config_path = os.path.join(project_root, 'cfg', 'predict.yaml')

            # 如果配置文件存在，先加载现有配置
            if os.path.exists(config_path):
                self.params_manager.load_from_yaml(config_path)

            # 获取当前界面中的参数值
            current_params = {}
            for key in self.params_manager.get_all_params().keys():
                if hasattr(self, f"{key}_var"):
                    var = getattr(self, f"{key}_var")
                    if isinstance(var, tk.BooleanVar):
                        current_params[key] = var.get()
                    elif isinstance(var, tk.StringVar):
                        # 尝试转换为适当的数据类型
                        value = var.get()
                        if value.lower() in ['true', 'false']:
                            current_params[key] = value.lower() == 'true'
                        elif value.isdigit():
                            current_params[key] = int(value)
                        else:
                            try:
                                current_params[key] = float(value)
                            except ValueError:
                                current_params[key] = value

            # 更新参数管理器中的参数
            for key, value in current_params.items():
                self.params_manager.set_param(key, value)

            # 保存到文件
            success = self.params_manager.save_to_yaml(config_path)
            if success:
                messagebox.showinfo("成功", "配置文件保存成功！")
            else:
                messagebox.showerror("错误", "无法保存配置文件！")
        except Exception as e:
            messagebox.showerror("错误", f"保存配置文件时发生异常: {str(e)}")


    def reset_defaults(self):
        """重置为默认值"""
        self.params_manager.reset_defaults()
        self.load_default_values()
        messagebox.showinfo("成功", "已重置为默认参数！")

# 使用示例
if __name__ == "__main__":
    root = tk.Tk()
    root.title("预测参数设置")
    root.geometry("600x500")

    # 创建参数管理器
    params_manager = PredictionParameters()

    # 创建预测框架
    predict_frame = PredictionFrame(root, params_manager)

    root.mainloop()
